﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Silverlight.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System8Equations;
using ObjectDirectory;

namespace t_System8Equations
{
    [TestClass]
    public class t_S8EqnSeriesAccumulator
    {
        [TestMethod]
        public void TestCTor()
        {
            S8EqnSeriesAccumulator eqn = new S8EqnSeriesAccumulator();
        }

        [TestMethod]
        public void TestSingleOutputNoInput()
        {
            S8EqnSeriesAccumulator eqn = new S8EqnSeriesAccumulator();
            var S8 = SetupS8StartingValues();
            eqn.S8 = S8;

            ObjectPathManager mgr = new ObjectPathManager();
            var wref = eqn.Watch(mgr.GetPath(S8, S8.n.TotalValue));

            eqn.Loop(100);
            var v = eqn.GetValueList(wref);

            Assert.AreEqual(100, v.Length, "Expected back 100 values");
            Assert.AreEqual(v[0], v[1], "Expected the first two values to be the same");
            Assert.AreEqual(30000, v[0], "Expected a nice total value there... what?");
        }

        [TestMethod]
        public void TestSingleOutputChangingInput()
        {
            S8EqnSeriesAccumulator eqn = new S8EqnSeriesAccumulator();
            var S8 = SetupS8StartingValues();
            eqn.S8 = S8;

            ObjectPathManager mgr = new ObjectPathManager();
            var wref = eqn.Watch(mgr.GetPath(S8, S8.n.TotalValue));

            double counter = 30000;
            eqn.SetOnIteration(mgr.GetPath(S8, S8.n.TotalValue), () => { counter += 3; return counter; });

            eqn.Loop(100);
            var v = eqn.GetValueList(wref);

            Assert.AreEqual(100, v.Length, "Expected back 100 values");
            Assert.AreEqual(v[0]+3.0, v[1], "Expected the first two values to be the same");
            Assert.AreEqual(30003, v[0], "Expected a nice total value there... what?");
        }

        [TestMethod]
        public void TestS8DoesntChange()
        {
            S8EqnSeriesAccumulator eqn = new S8EqnSeriesAccumulator();
            var S8 = SetupS8StartingValues();
            eqn.S8 = S8;

            ObjectPathManager mgr = new ObjectPathManager();
            var wref = eqn.Watch(mgr.GetPath(S8, S8.n.TotalValue));

            double counter = 30000;
            eqn.SetOnIteration(mgr.GetPath(S8, S8.n.TotalValue), () => { counter += 3; return counter; });

            eqn.Loop(100);

            Assert.AreEqual(10000, S8.n.Bottom, "Expected the original S8 not to have changed!");
        }

        [TestMethod]
        public void TestSettingVariable()
        {
            S8EqnSeriesAccumulator eqn = new S8EqnSeriesAccumulator();
            eqn.S8 = SetupS8StartingValues();
            eqn.SetOnIteration(new UniformS8Variable(eqn.S8.n.Total) { Path = "n/TotalValue", MinValue = eqn.S8.n.Total - 10, MaxValue = eqn.S8.n.Total + 10 });
            var wref = eqn.Watch("n/TotalValue");
            eqn.Loop(1000);
            var results = eqn.GetValueList(wref);
            Assert.AreEqual(1000, results.Length);
        }

        [TestMethod]
        public void TestSettingVariableUpdates()
        {
            S8EqnSeriesAccumulator eqn = new S8EqnSeriesAccumulator();
            var vals = SetupS8StartingValues();
            eqn.S8 = vals;
            UniformS8Variable uf = new UniformS8Variable(500) {Path = "n/TotalValue", MinValue = 450, MaxValue=550};
            eqn.SetOnIteration(uf);
            var wref = eqn.Watch("n/TotalValue");
            eqn.Loop(1000);

            Assert.AreEqual(vals.n.Total * 1.1, uf.MaxValue, "Max is not set correctly");
            Assert.AreEqual(vals.n.Total * 0.9, uf.MinValue, "Min value is not set correctly");
        }

        /// <summary>
        /// Setup a nice starting point.
        /// </summary>
        /// <returns></returns>
        private System8Equations.S8Equations SetupS8StartingValues()
        {
            System8Equations.S8Equations eqn = new System8Equations.S8Equations();

            eqn.n.Bottom = 10000;
            eqn.n.Charm = 10000;
            eqn.n.Light = 10000;

            eqn.n1.Bottom = 5000;
            eqn.n1.Charm = 5000;
            eqn.n1.Light = 5000;

            eqn.n2.Bottom = 5000;
            eqn.n2.Charm = 5000;
            eqn.n2.Light = 5000;

            eqn.n12.Bottom = 2500;
            eqn.n12.Charm = 2500;
            eqn.n12.Light = 2500;

            eqn.p.Bottom = 10000;
            eqn.p.Charm = 10000;
            eqn.p.Light = 10000;

            eqn.p1.Bottom = 5000;
            eqn.p1.Charm = 5000;
            eqn.p1.Light = 5000;

            eqn.p2.Bottom = 5000;
            eqn.p2.Charm = 5000;
            eqn.p2.Light = 5000;

            eqn.p12.Bottom = 2500;
            eqn.p12.Charm = 2500;
            eqn.p12.Light = 2500;

            return eqn;
        }
    }
}